import { State } from "framework/FSM/AState";
import { ActionArgHelper } from "../../../ActionManager/ActionArgHelper";
import { EntityHelper } from "utils/entity/EntityHelper";
import { PositionHelper } from "utils/position/PositionHelper";
import { ActionUtils } from "../utils/ActionUtil";
 

/**
 * 行为模式
 * 采集行为
 * 升级行为
 */ 
export class RepairTask<T extends IStateArg<Creep>>  extends State<T>
{

    //
    public  getActions(arg:T):Action[]
    {
        const creep = arg.entity;
        if(!creep.memory.taskid)
        {
            return []
        }
        const task =arg.task as ITask<ICreepTaskData<"repair">>;
        if(!task)
        {
            return []
        }
        const actions = ActionUtils.getEscapeSourceKeeperAction(arg.entity);
        if(actions)
        {
            return actions
        }
        // 检测
        if(creep.memory.targetId)
        {
            const obj = (Game.getObjectById(creep.memory.targetId) as AnyStoreStructure);
            const target = task.data.arg.targets.find(e=>e[0] == creep.memory.targetId)
            if(!obj || (target&& target[1]<=obj.hits))
            {
                // 不存在或者满了都需要更换目标,还要清理任务
                // 修满了
            
                delete creep.memory.targetId;
            }
        }
        
       
        if(creep.store.getUsedCapacity()==0)
        {
            creep.memory.state = 0;

        }
        else   
        {
            // 有能量就可以去修理了
            creep.memory.state = 1;
        }
        if(creep.memory.state)
        {
            const targets = task.data.arg.targets;
            // 运
            if(!creep.memory.targetId)
            {
                // 任意取一个移动目标
                let idx = Math.floor(Math.random()*targets.length );
                if(creep.room.name == creep.ownerRoom().name && !creep.ownerRoom().isSafe())
                {
                    const minobj = _.min(targets,e=>
                        {
                            const obj = Game.getObjectById(e[0]);
                            if(obj)
                            {
                                return obj.hits;
                            }
                            return 1000000000;
                        })
                    creep.memory.targetId = minobj[0];
                }
                else 
                {
                    creep.memory.targetId = targets[idx][0];
                }
                
            }
            // 附近没有需要填充的目标
            let repairindex=0;
            for(let i=0;i<targets.length;i++)
            {
                const curgoal  = targets[i];
                const  target = Game.getObjectById(curgoal[0]) as AnyStoreStructure;
                if(!target || curgoal[1]<=target.hits)
                {
                    // 不存在或者满了
                     task.data.arg.targets.splice(i,1);
                    continue;
                }
                // 否则判断是否在爬附近
                if(target.pos.inRangeTo(creep.pos,3))
                {
                    // 在附近
                    creep.memory.targetId = target.id;
                    return [ActionArgHelper.actionRepair(creep,target,curgoal[1])];
                }
                repairindex=i;
            }
            const obj = Game.getObjectById(creep.memory.targetId) as AnyOwnedStructure;
            if(   obj &&task.data.arg.targets&& task.data.arg.targets[repairindex]&& obj.hits<task.data.arg.targets[repairindex][1])
            {
                return [ActionArgHelper.actionMoveto(creep,{pos: obj.pos,range:3},{})];
            }
            else
            {
                creep.memory.targetId=undefined;
            }
            
        }
        else
        {
            // 取能量,首先从core 取。其次从 spawn 取
            
            
            const core = arg.entity.getEntity("CoreEntity",creep.memory.OwnerRoom);
            const store = core.getTakeStores({resourceType:RESOURCE_ENERGY,amount:creep.store.getFreeCapacity()})
            if(store.length>0)
            {
                return [ActionArgHelper.actionWithdraw(creep,store[0],[{resourceType:RESOURCE_ENERGY}])]
            }

            const spawnentity = arg.entity.getEntity("SpawnEntity",creep.memory.OwnerRoom);
            const ids = spawnentity.getContainer();
            for(const id of ids)
            {
                const container = Game.getObjectById(id)
                if(container && container.store.getUsedCapacity(RESOURCE_ENERGY)>creep.store.getFreeCapacity())
                {
                    return [ActionArgHelper.actionWithdraw(creep,container,[{resourceType:RESOURCE_ENERGY}])]
                }
            }
        }
        return [ ];
    }
}
